package com.karina.visualization.chart.skins;

import com.karina.visualization.chart.client.Gradient;
import com.karina.visualization.chart.client.Graphics;
import com.karina.visualization.chart.model.SeriesModel;
import com.karina.visualization.chart.model.SeriesModel.CategoryValue;

public class BucketSkin extends BaseSkin<SeriesModel<CategoryValue>> {

	// private Color current_color;
	private Gradient current_graident;
	private final static int INDICATOR_LINE_LENGTH = 80;

	@Override
	public void draw(Graphics grahpics) {
		drawFrame(grahpics);
	}

	private final static int ELLIPSE_HEIGHT = 30;

	public void drawFrame(Graphics graphics) {

		int width = (Integer) getStyleDeclaretion().getStyle("width");
		int height = (Integer) getStyleDeclaretion().getStyle("height");
		if (width == 0)
			width = 100;

		if (height == 0) {
			height = 120;
		}

		int x = getData().getWidth() / 2 - width / 2;
		int y = getData().getHeight() / 2 - height / 2;

		graphics.saveContext();
		graphics.beginPath();

		graphics.moveTo(x, y);
		graphics.lineTo(x, height + y);

		graphics.moveTo(x + width, y);
		graphics.lineTo(x + width, height + y);
		graphics.stroke();

		// graphics.fill();
		if (getData().getIndex() == 0) {
			drawEllipse(graphics, x, y - ELLIPSE_HEIGHT / 2 + height, width,
					ELLIPSE_HEIGHT);
		} else {
			drawBottomEllipse(graphics, x, y - ELLIPSE_HEIGHT / 2 + height,
					width, ELLIPSE_HEIGHT);
		}
		graphics.endPath();
		drawPortions(graphics, x, y, width, height);

		graphics.beginPath();
		drawEllipse(graphics, x, y - ELLIPSE_HEIGHT / 2, width, ELLIPSE_HEIGHT);
		graphics.endPath();
		graphics.restoreContext();
	}

	private void drawPortions(Graphics g, int x, int y, int width, int height) {
		SeriesModel<CategoryValue> seriesModels = getData();
		double value = (Double) seriesModels.getValue().getValue();
		double relativePosition = seriesModels.getRelativeX();
		int y0 = (int) (height - height * relativePosition) + y;
		int x0 = x;
		int width0 = width;
		int height0 = (int) (height * value);

		drawPortion(g, x0, y0 - height0, width0, height0);
	}

	private void drawPortion(Graphics g, int x, int y, int width, int height) {
		g.saveContext();
		g.setGlobalAlpha(0.8);

		g.beginPath();
		getStyleDeclaretion().getStyle("color");
		if (current_graident == null) {
			// current_color = Graphics.PRE_DEFINED_COLOR_ARRAY[getData()
			// .getIndex()];

			current_graident = Graphics.PRE_DEFINED_GRADIENT_ARRAY[getData()
					.getIndex()];
		}

		// g.fillStyle(current_color.r, current_color.g, current_color.b, 0.8);
		g.fillStyle(x, y, x + width, y + height, current_graident);
		g.shallow(4, 4, 6, 240, 240, 240, 0.8);

		drawEllipse(g, x, y - ELLIPSE_HEIGHT / 2, width, ELLIPSE_HEIGHT);
		g.strokeWidth(0);
		g.moveTo(x, y);

		g.lineTo(x + width / 2, y - ELLIPSE_HEIGHT / 2).lineTo(x + width, y)
				.lineTo(x, y);

		// g.endPath();

		int x0 = x;
		int y0 = y;

		int x1 = x + width / 2;

		int x2 = x1 + width / 2;
		int y2 = y;

		int x3 = x2;
		int y3 = y2 + height;

		int xc2 = x3;
		int yc2 = y3 + ELLIPSE_HEIGHT / 2;

		int x4 = xc2 - width / 2;
		int y4 = yc2;

		int x5 = x3 - width;
		int y5 = y3;

		g.moveTo(x0, y0);
		g.lineTo(x2, y2);
		g.lineTo(x3, y3);
		g.lineTo(x5, y5);
		g.lineTo(x3, y3);
		g.lineTo(x5, y5);
		g.lineTo(x0, y0);

		// g.strokeWidth(1);
		drawEllipse(g, x5, y5 - ELLIPSE_HEIGHT / 2, width, ELLIPSE_HEIGHT);

		g.moveTo(x3, y3).lineTo(x4, y4).lineTo(x5, y5).fill();

		g.endPath();
		g.restoreContext();
		g.saveContext();
		int index = getData().getIndex();
		if (index % 2 == 0) {
			drawRightText(g, x2, y2);
		} else {
			drawLeftTest(g, x, y);
		}
		g.restoreContext();
	}

	private void drawLeftTest(Graphics g, int x, int y) {
		g.beginPath();
		g.moveTo(x, y);
		g.lineTo(x - INDICATOR_LINE_LENGTH - 5, y);
		g.setLineWidth(1);
		g.stroke();
		int num = (int) (((Double) getData().getValue().getValue()) * 100 % 100);
		g.drawText(x - INDICATOR_LINE_LENGTH - 5, y, getData().getValue()
				.getDescription() + "\n\r" + num + "%", "left", "bottom");
		g.endPath();
	}

	private void drawRightText(Graphics g, int x, int y) {
		g.beginPath();
		g.moveTo(x, y);
		g.lineTo(x + INDICATOR_LINE_LENGTH, y);
		g.setLineWidth(1);
		g.stroke();
		int num = (int) (((Double) getData().getValue().getValue()) * 100 % 100);
		g.drawText(x + INDICATOR_LINE_LENGTH + 5, y, getData().getValue()
				.getDescription() + "\n\r" + num + "%", "right", "bottom");
		g.endPath();
	}

	private void drawEllipse(Graphics g, int x, int y, int width, int height) {
		int x0 = x;
		int y0 = y + height / 2;
		int xc0 = x0;
		int yc0 = y0 - height / 2;

		int x1 = xc0 + width / 2;
		int y1 = yc0;

		int xc1 = x1 + width / 2;
		int yc1 = y1;

		int x2 = xc1;
		int y2 = yc1 + height / 2;

		int xc2 = x2;
		int yc2 = y2 + height / 2;

		int x3 = xc2 - width / 2;
		int y3 = yc2;

		int xc3 = x3 - width / 2;
		int yc3 = yc2;

		g.drawQuadraticChart(xc0, yc0, x0, y0, x1, y1).drawQuadraticChart(xc1,
				yc1, x1, y1, x2, y2);

		g.drawQuadraticChart(xc2, yc2, x2, y2, x3, y3).drawQuadraticChart(xc3,
				yc3, x3, y3, x0, y0);
		g.stroke();
	}

	private void drawBottomEllipse(Graphics g, int x, int y, int width,
			int height) {
		int x0 = x;
		int y0 = y + height / 2;
		int xc0 = x0;
		int yc0 = y0 - height / 2;

		int x1 = xc0 + width / 2;
		int y1 = yc0;

		int xc1 = x1 + width / 2;
		int yc1 = y1;

		int x2 = xc1;
		int y2 = yc1 + height / 2;

		int xc2 = x2;
		int yc2 = y2 + height / 2;

		int x3 = xc2 - width / 2;
		int y3 = yc2;

		int xc3 = x3 - width / 2;
		int yc3 = yc2;

		g.drawQuadraticChart(xc2, yc2, x2, y2, x3, y3).drawQuadraticChart(xc3,
				yc3, x3, y3, x0, y0);
		g.stroke();
	}

	@Override
	public void cleanup(Graphics graphics) {

	}

	@Override
	public void refresh(Graphics graphics) {
		draw(graphics);
	}

}
